package com.douwong.student.synscreen;

import android.util.Log;

import com.douwong.student.contant.CommonConfig;
import com.douwong.student.utils.LogUtils;
import com.douwong.student.utils.TimeUtils;

import org.apache.mina.core.buffer.IoBuffer;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.zip.GZIPInputStream;

public class SynUdpService {

    private static final String TAG = SynUdpService.class.getName();
    private MulticastSocket mSocket = null;
    private InetAddress mAddress = null;
    private boolean mRuning = false;
    private SynData mData = null;
    private ExecutorService mExecutorService = null;
    private ScreenDataNotify dataNotify = null;


    public void setScreenDataChangeListener(ScreenDataNotify dataNotify) {
        this.dataNotify = dataNotify;
    }


    public SynUdpService() {
        mExecutorService = Executors.newFixedThreadPool(10);

    }

    public void start() {
        if (mSocket != null) {
            Log.w(TAG, "mSocket not null....");
            return;
        }
        mRuning = true;
        new Thread() {
            @Override
            public void run() {
                try {
                    mSocket = new MulticastSocket(CommonConfig.UDP_BROADCAST_PORT);
                    mAddress = InetAddress.getByName(CommonConfig.UDP_BROADCAST_IP);
                    mSocket.joinGroup(mAddress);
                    mSocket.setTimeToLive(1);
                    mData = new SynData();
                			//		mSocket.setReceiveBufferSize(CommonConfig.UDP_BROADCAST_SIZE*10);
                    LogUtils.i(SynScreenActivity.TAG,"开始接受数据 时间： "+ TimeUtils.getTime());
                    while (mRuning) {
                        LogUtils.i(SynScreenActivity.TAG,"开始接受数据 mRuning ： "+ TimeUtils.getTime());
                        byte[] bytes = new byte[CommonConfig.UDP_BROADCAST_SIZE];
                        DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);
                        mSocket.receive(datagramPacket);
                        String clientStr=new String(datagramPacket.getData(),datagramPacket.getOffset());
                        mExecutorService.execute(new LoadDataThread(bytes));
                        LogUtils.i(SynScreenActivity.TAG,"开始接受数据 clientStr ： "+ clientStr.getBytes().length);
                    }
                } catch (Exception e) {
                    //??怎么处理

                    e.printStackTrace();
                }
            }
        }.start();

    }

    public void stop() {

        mRuning = false;
        try {
            mSocket.leaveGroup(mAddress);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        if (mSocket != null) {
            mSocket.disconnect();
            mSocket.close();
            mSocket = null;
        }

        mExecutorService.shutdown();
    }

    class LoadDataThread implements Runnable {


        private byte[] bytes;
        private boolean loadok = true;

        public LoadDataThread(byte[] bytes) {
            this.bytes = bytes;
        }
        @Override
        public void run() {
            IoBuffer buffer = IoBuffer.wrap(bytes);

            int uid = buffer.getInt();
            int count = buffer.getInt();
            int index = buffer.getInt();
            int offset = CommonConfig.UDP_BROADCAST_BODYSIZE * index;
          //  LogUtils.i(URLConfig.TAG, "该数据的 大小"+buffer.limit());
            LogUtils.i(SynScreenActivity.TAG, "该数据的 uid: "+uid + "分包数量 " + count + "包的顺序:" + index+"**************"+uid+index);

            if (mData.uid != uid) {
                mData.reset(uid, count);
            }

            try {

                while (buffer.hasRemaining()) {
                    mData.data[offset] = buffer.get();
                    offset++;
                }
                LogUtils.i(SynScreenActivity.TAG,"数据大小： ： "+   mData.data.length);

                mData.total++;

            } catch (Exception e) {
                // TODO: handle exception
                loadok = false;
                e.printStackTrace();
                LogUtils.i(SynScreenActivity.TAG,"数据接受完成 出现异常： ： "+ TimeUtils.getTime());
            }
            if (mData.count == mData.total && loadok) {
                LogUtils.i(SynScreenActivity.TAG,"数据接受完成 ： ： "+ TimeUtils.getTime());
                dataNotify.DataChangeNotify(mData.data);
      /*          byte[] bytes = UnGZip(mData.data);
                LogUtils.i(SynScreenActivity.TAG,"解压数据完成 ： "+ TimeUtils.getTime());

                if (bytes != null) {
                    dataNotify.DataChangeNotify(bytes);
                    Log.d("===", mData.uid + "== ok");
                }*/
            }
            buffer.clear();
        }
    }

    /***
     * UnGzip
     *
     * @param data
     * @return
     */

    public static byte[] UnGZip(byte[] data) {
        byte[] b = null;
        try {
            ByteArrayInputStream bis = new ByteArrayInputStream(data);
            GZIPInputStream gzip = new GZIPInputStream(bis);
            byte[] buf = new byte[1024];
            int num = -1;
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            while ((num = gzip.read(buf, 0, buf.length)) != -1) {
                baos.write(buf, 0, num);
            }
            b = baos.toByteArray();
            baos.flush();
            baos.close();
            gzip.close();
            bis.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return b;
    }


    public interface ScreenDataNotify {
        void DataChangeNotify(byte[] bytes);
    }

}
